package com.aube.video;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.annotation.TargetApi;
import android.graphics.Bitmap;
import android.os.Build;
import android.os.Handler;
import android.os.Message;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.aube.R;
import com.aube.StaticApplicationContext;
import com.aube.activity.DanmukuFlameHelper;
import com.aube.control.CardControllerDispatcher;
import com.aube.control.DataManager;
import com.aube.control.player.AbstractVideoHelper;
import com.aube.control.player.MultiVideoBalanceAdapter;
import com.aube.guide.GuideConstants;
import com.aube.guide.OnGuidePerformedListener;
import com.aube.model.ChannelDetailModel;
import com.aube.model.MessageModel;
import com.aube.multiscreen.AbsPlayCallback;
import com.aube.multiscreen.CameraCardView;
import com.aube.multiscreen.MultiCameraView;
import com.aube.multiscreen.VRCardView;
import com.aube.multiscreen.VRMixedCardView;
import com.aube.utils.BlurUtil;
import com.aube.video.module.OnAubePreparedListener;
import com.aube.video.module.PlayerModuleManager;
import com.huyn.baseframework.ImageLoader;
import com.huyn.baseframework.dynamicload.video.AbstractController;
import com.huyn.baseframework.dynamicload.video.DLVideoLayout;
import com.huyn.baseframework.dynamicload.video.IPlayController;
import com.huyn.baseframework.dynamicload.video.IPlayPresenter;
import com.huyn.baseframework.dynamicload.video.ISeekable;
import com.huyn.baseframework.dynamicload.video.model.GoodsItem;
import com.huyn.baseframework.model.Category;
import com.huyn.baseframework.model.ChannelDetail;
import com.huyn.baseframework.net.BFJSONRequest;
import com.huyn.baseframework.net.HttpRequestLoader;
import com.huyn.baseframework.net.OpenApi;
import com.huyn.baseframework.statistics.AubeStatisticEvents;
import com.huyn.baseframework.statistics.AubeStatisticTool;
import com.huyn.baseframework.statistics.EventValuePair;
import com.huyn.baseframework.utils.ImageParamUtils;
import com.huyn.baseframework.utils.StringUtils;
import com.huyn.baseframework.utils.SysUtil;
import com.huyn.baseframework.utils.Utils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;

import master.flame.danmaku.ui.widget.DanmakuView;

/**
 * Created by huyaonan on 16/11/1.
 */
public class PlayerProxy implements IPlayController, AbstractController.IControllerCallback {

    public static final String TAG = "PlayerProxy";

    private PlayActivity mPlayActivity;

    public CameraCardView mMajorVideo;
    private AbstractVideoHelper mMajorVideoHelper;

    private ChannelDetail mChannel;
    private Category mCategory;

    private long lastPosition = 0;

    private IPlayPresenter mPlayController;

    private View mViewRoot;

    private CardControllerDispatcher mDispatcher;

    private AtomicBoolean mToolVisible = new AtomicBoolean(true);
    private AtomicBoolean mAnimating = new AtomicBoolean(false);
    private AtomicBoolean mBuffering = new AtomicBoolean(false);
    private AtomicBoolean mBufferingEnd = new AtomicBoolean(true);

    private AtomicBoolean mRestartToolVisibilityLooper = new AtomicBoolean(false);

    private View mInitLoading;
    private ImageView mBgImg;

    private TextView mProxyLog;

    private MultiCameraView mMultiCameraView;

    private FrameLayout mControllerLayout;

    private DanmukuFlameHelper mDanmuHelper;
    private MessageHelper mMessageHelper;
    private DanmakuView mDanmuView;

    private AtomicBoolean mLoadintAnimating = new AtomicBoolean(false);
    private long mCurrentProgress = 0;
    private long mReplayTargetPosition = 0;
    private AtomicBoolean mErrorHappend = new AtomicBoolean(false);

    /**
     * onWindowFocusChanged onPause onResume相关参数 start
     */
    private AtomicBoolean mInvokeWindowFocusChanged = new AtomicBoolean(true);
    private AtomicBoolean mFocusState = null;
    private AtomicBoolean mFocusSwitchEnable = new AtomicBoolean(false);
    /**
     * onWindowFocusChanged onPause onResume相关参数 end
     */

    private boolean canDrag = false;

    private long mVideoDuration = 0;
    private long mSeekTargetPosition = 0;

    private static final int CODE_SHOW = 1;
    private static final int CODE_HIDE = 2;
    private static final int CODE_HIDE_TOOLS = 3;
    private static final int TOOL_DURATION = 5000;

    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            if (mAnimating.get())
                return;
            switch (msg.what) {
                case CODE_HIDE:
                    manageToolVisibleState(true);
                    break;
                case CODE_SHOW:
                    manageToolVisibleState(false);
                    break;
                case CODE_HIDE_TOOLS:
                    manageToolVisibleState(true, false);
                    break;
            }
        }
    };

    private View findViewById(int id) {
        return mPlayActivity.findViewById(id);
    }

    public PlayerProxy(PlayActivity activity, ChannelDetail channelDetail, Category category) {
        this.mPlayActivity = activity;
        this.mChannel = channelDetail;
        this.mCategory = category;

        mBgImg = (ImageView) findViewById(R.id.aube_bg);

        mInitLoading = findViewById(R.id.init_loading);
//        mInitLoading.setOnClickListener(new View.OnClickListener() {
//            @Override
//            public void onClick(View v) {
//                //do nothing
//            }
//        });

        mMultiCameraView = (MultiCameraView) findViewById(R.id.transition_video);

        mDanmuView = (DanmakuView) findViewById(R.id.danmu);

        int sizePaddingTop = SysUtil.getStatusBarHeight(mPlayActivity);
        if (sizePaddingTop > 0) {
            RelativeLayout.LayoutParams paramsDanmu = (RelativeLayout.LayoutParams) mDanmuView.getLayoutParams();
            paramsDanmu.setMargins(0, sizePaddingTop, 0, 0);
        }

        mViewRoot = findViewById(R.id.root);
        mControllerLayout = (FrameLayout) findViewById(R.id.play_controller_layout);

        mViewRoot.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                manageTools();
            }
        });

        mProxyLog = (TextView) findViewById(R.id.proxy_log);
        mProxyLog.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                StaticApplicationContext.RECEIVED_DATA_SIZE = 0;
                StaticApplicationContext.receivedDataSize = 0;
            }
        });
        StaticApplicationContext.RECEIVED_DATA_SIZE = 0;
        StaticApplicationContext.receivedDataSize = 0;

        //统计多镜头播放次数
        DataManager.getInstance(mPlayActivity).updateVideoPlayCount(mChannel.videoid, false);
        AubeStatisticTool.getInstance(mPlayActivity).report(AubeStatisticEvents.VIDEO_PLAY_COUNTT,
                AubeStatisticEvents.formatValues(new EventValuePair("vid", mChannel.videoid),
                        new EventValuePair("playcount", String.valueOf(DataManager.getInstance(mPlayActivity).getVideoPlayCount(mChannel.videoid)))));
    }

    public void init() {
        loadChannelDetail(loadModule());
    }

    private boolean loadModule() {
        if (mChannel == null || mChannel.getVideo() == null)
            return false;

        PlayerModuleManager.getInstance(mPlayActivity).load(mPlayActivity, mControllerLayout, mChannel.videoid, new OnAubePreparedListener() {
            @Override
            public void onPrepared(DLVideoLayout layout) {
                setupPlayer(layout);
            }

            @Override
            public void onError(Exception e) {
                setupPlayer(null);
            }
        });

//        setupPlayer(PlayerModuleManager.getInstance(mPlayActivity).test(mPlayActivity, mControllerLayout));
//        setupPlayer(null);

        //for localTest
//        DLVideoLayout layout = new AubePlayController(mPlayActivity);
//        layout.initViews();
//        mControllerLayout.addView(layout, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
//        setupPlayer(layout);

        return true;
    }

    private void setupPlayer(DLVideoLayout layout) {
        if (mChannel.isVr()) {
            mMajorVideo = new VRCardView(mPlayActivity);
        } else {
//            mMajorVideo = new CameraCardView(mPlayActivity);
            mMajorVideo = new VRMixedCardView(mPlayActivity);
        }
        mMultiCameraView.removeAllViews();
        mMultiCameraView.addView(mMajorVideo, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));

        mMajorVideo.setTag("0");
        mMajorVideo.setTag(R.id.card_index, 0);

        if (layout == null) {
            mPlayController = new PlayController(mViewRoot);
        } else {
            layout.setDLBridge(new SimpleBridge(mPlayActivity));
            mPlayController = layout;
        }

        mPlayController.init(mChannel, mCategory, mPlayActivity, this);

        mDanmuHelper = new DanmukuFlameHelper();
        mDanmuHelper.init(mDanmuView);
        mMessageHelper = MessageHelper.getInstance(mPlayActivity, mChannel.videoid, new MessageHelper.IMessageDispatcher() {
            @Override
            public void dispatchResponse(MessageModel model) {
                mDanmuHelper.importDanmuMap(model);
            }
        });
        mMessageHelper.fetchMessage(0);

        mErrorHappend.set(false);
        mMajorVideoHelper = mMajorVideo.getVideoHelper(mChannel.getVideo(), mChannel.leftRightAngle, mChannel.updownAngle, new AbsPlayCallback() {
            @Override
            public void startPlay() {
                mMajorVideo.onVideoPrepared();

                mPlayController.updateState(true);
            }

            @Override
            public void endPlay() {
                if (canDrag) {
                    hideLoading();
                    mDispatcher.endPlay();
                    mPlayController.endPlay();

                    //show cart
                    mPlayController.showGoodsCart();
                }
            }

            @Override
            public void updatePlay(long current, long duration) {
                mCurrentProgress = current;
                if (!canDrag) {
                    if (current > 100) {
                        canDrag = true;
                        if(mPlayController != null)
                            mPlayController.enableSeekBar();

                        if(mDanmuHelper != null)
                            mDanmuHelper.startDanmaku(mPlayActivity);

                        removeLoadint();

                        mMajorVideo.removeMask();

                        if (mMajorVideo.isVr())
                            GuideConstants.showVrGuide(mPlayActivity, mMajorVideo, mMajorVideo.supportVRMotionMode(), null);
                    }
                }

                if (canDrag && mPlayController.updateProgress(current, duration)) {
                    //负载均衡调节
                    if (AbstractVideoHelper.ENABLE_SOCKET_PROXY) {
                        mMultiCameraView.balanceVideoProgress(mMajorVideoHelper, mProxyLog);
                    }

                    if (mPlayController.updateProgress(current, duration)) {
                        if(Math.abs(mSeekTargetPosition - current) > 100) {
                            mDispatcher.loadCard(current);
                        }

                        if(Math.abs(current-duration) < 1000) {
                            hideLoading();
                            return;
                        }

                        if (lastPosition == current) {
                            showLoading();

                            if(mBufferingEnd.get()) {
                                mBuffering.set(true);
                                mBufferingEnd.set(false);
                                onBufferingStartEvent();
                            }
                        } else {
                            if(mDanmuHelper.isOn() && mDanmuView.isPaused()) {
                                mDanmuHelper.onResume();
                            }
                            hideLoading();
                            lastPosition = current;

                            if(mBuffering.get()) {
                                mBufferingEnd.set(true);
                                mBuffering.set(false);
                                onBufferingEndEvent();
                            }
                        }
                    }
                }
            }

            @Override
            public void updateBuffer(int progress) {
                mPlayController.updateBuffer(progress);
            }

            @Override
            public boolean hasFocused() {
                if (mFocusState == null)
                    return false;
                return mFocusState.get();
            }

            @Override
            public void onError() {
            }

            @Override
            public void clearLoading() {
                mMajorVideo.hideLoading();
            }

            @Override
            public void onReceiveDefinition(Map<Integer, String> definitions, int currentCode) {
                mPlayController.setupResolutions(definitions, currentCode);
            }

            @Override
            public void onDecoderInitializationError(long position) {
                mReplayTargetPosition = position;
                mErrorHappend.set(true);
            }

            @Override
            public long getTargetPosition() {
                return mReplayTargetPosition;
            }
        });

        mMajorVideoHelper.initAdState(mPlayActivity.isAdPlaying());
        //防止vrcardview的onresume没有执行
        mMajorVideo.onResume();
        mMajorVideo.setHelper(mMajorVideoHelper);
        mMajorVideo.setIVideoParentConnector(mMultiCameraView);

        mPlayController.initToolBar(true);
        mPlayController.setVideoHelper(mMajorVideoHelper);

        mDispatcher = new CardControllerDispatcher(mPlayActivity, mViewRoot, mChannel, this);
        if (mPlayController != null)
            mDispatcher.addControllers(mPlayController.getControllers());
        mDispatcher.initData(0, true, true);

        mHandler.sendEmptyMessageDelayed(CODE_HIDE, TOOL_DURATION);
    }

    public void manageToolVisibleState(final boolean hide) {
        manageToolVisibleState(hide, true);
    }

    public void manageToolVisibleState(final boolean hide, boolean manageStatus) {
        mAnimating.set(true);
        if(manageStatus)
            setFullScreenMode(hide);
        if(mPlayController != null)
            mPlayController.manageToolVisibleState(hide, manageStatus);
    }

    @TargetApi(19)
    public void setFullScreenMode(boolean fullscreen) {
        if(Build.VERSION.SDK_INT >= 19) {
            if (fullscreen)
                mPlayActivity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
            else
                mPlayActivity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
        }
    }

    /**
     * implements IPlayController
     */
    @Override
    public void onProgressChanged(ISeekable seekBar, int progress, boolean fromUser, boolean refreshCardList) {
        if (fromUser) {
            int tartget = (int) (progress * getVideoDuration() / seekBar.getMax());
            Utils.Log(TAG, "onProgressChanged:::" + progress + "/" + tartget + "/" + getVideoDuration() + "/" + seekBar.getMax());

            if (refreshCardList) {
                updatePlay(tartget);
            }
        }
    }

    @Override
    public void onLocateProgress(int progress) {
        if (progress >= 0 && progress <= getVideoDuration())
            updatePlay(progress);
    }

    private long getVideoDuration() {
        if(mVideoDuration == 0) {
            if (mChannel.duration > 0)
                mVideoDuration = mChannel.duration * 1000;
            if (getDuration() > 0)
                mVideoDuration = getDuration();
        }
        return mVideoDuration;
    }

    @Override
    public void onUpdateToolState(boolean visible) {
        mToolVisible.set(visible);
        mAnimating.set(false);
    }

    @Override
    public void finish() {
        mPlayActivity.onBackKeyPressed(KeyEvent.KEYCODE_BACK, null);
    }

    @Override
    public void reverseFromFullScreen() {
        if (mDispatcher == null)
            return;
        mDispatcher.reverseFromFullScreen();
    }

    @Override
    public void pause() {
        mDispatcher.pause();
    }

    @Override
    public void pauseWhenFreeze() {
        mDispatcher.pauseWhenFreeze();
    }

    @Override
    public void start() {
        /** 出错重播 */
        if(mErrorHappend.get()) {
            switchVideo(mChannel);
            return;
        }

        mDispatcher.start();

        mDanmuHelper.onResume();

        //在multicameraview已经做了控制
        if (!MultiVideoBalanceAdapter.getInstance().isLowExperience())
            mMajorVideoHelper.startPlay();

        if (mRestartToolVisibilityLooper.get()) {
            mHandler.sendEmptyMessageDelayed(CODE_HIDE, TOOL_DURATION);
            mRestartToolVisibilityLooper.set(false);
        }
    }

    @Override
    public void hidePauseAD() {
        mPlayActivity.hidePauseAD();
    }

    @Override
    public void showPauseAD() {
        mPlayActivity.showPauseAD();
    }

    @Override
    public boolean isSoundOn() {
        //工具栏声音状态
        return mMajorVideoHelper.isSoundOn();
    }

    @Override
    public void manageSound(boolean open) {
        //工具栏的声音开关
        mMajorVideoHelper.manageSound(open);
    }

    @Override
    public void removeHideMessage() {
        mHandler.removeMessages(CODE_HIDE);
    }

    @Override
    public void sendHideMessage() {
        mHandler.removeMessages(CODE_HIDE);
        mHandler.sendEmptyMessageDelayed(CODE_HIDE, TOOL_DURATION);
    }

    @Override
    public boolean onBack() {
        return mDispatcher.onBack();
    }

    @Override
    public void doLogin() {
        mPlayActivity.showLoginLayout();

        mPlayController.pauseWhenLogin();
    }

    @Override
    public void hideCart() {
        mPlayController.hideGoodsCart();
    }

    @Override
    public void clearHandlerMsg() {
        mHandler.removeMessages(CODE_HIDE);
        mHandler.removeMessages(CODE_SHOW);
        mHandler.removeMessages(CODE_HIDE_TOOLS);
    }

    @Override
    public boolean isDanmuOn() {
        return mDanmuHelper.isOn();
    }

    @Override
    public void hideDanmu() {
        mDanmuHelper.hide();
    }

    @Override
    public void showDanmu() {
        mDanmuHelper.show();
    }

    @Override
    public void resumeDanmu() {
        mDanmuHelper.onResume();
    }

    @Override
    public void pauseDanmu() {
        mDanmuHelper.onPause();
    }

    @Override
    public void sendDanmu(String content, String videoId, int progress) {
        mDanmuHelper.addDanmaku(content);
        mMessageHelper.sendMessage(content, videoId, progress);
    }

    @Override
    public void manageMessageProgress(long current) {
        if(mMessageHelper != null)
            mMessageHelper.manageProgress(current);
    }

    @Override
    public boolean isLowExperience() {
        return MultiVideoBalanceAdapter.getInstance().isLowExperience();
    }

    @Override
    public boolean shouldRequestStoragePermission() {
        return mPlayActivity.shouldRequestPermission();
    }

    @Override
    public void onBufferingStartEvent() {
        mPlayController.onBufferingStartEvent();
    }

    @Override
    public void onBufferingEndEvent() {
        mPlayController.onBufferingEndEvent();
    }

    @Override
    public void switchVideo(ChannelDetail channelDetail) {
        Utils.Log(TAG, "[switchVideo] channeDetail.videoTitle " + channelDetail.videoTitle);
        mErrorHappend.set(false);
        if(mMultiCameraView != null) {
            mMultiCameraView.reset();
        }
        if(mDispatcher != null) {
            mDispatcher.onDestroy();
            mDispatcher = null;
        }
        if (mPlayController != null) {
            mPlayController.onDestroy();
            mControllerLayout.removeAllViews();
        }
        if(mMessageHelper != null) {
            mMessageHelper.onDestroy();
            mMessageHelper = null;
        }
        if(mDanmuHelper != null) {
            mDanmuHelper.onDestroy();
            mDanmuHelper = null;
        }

        mChannel = channelDetail;

        lastPosition = 0;
        mBuffering.set(false);
        mBufferingEnd.set(false);
        mRestartToolVisibilityLooper.set(false);
        mLoadintAnimating.set(false);
        mCurrentProgress = 0;
        canDrag = false;

        resetLoading();

        init();
    }

    @Override
    public void updatePlay(long target) {
        mSeekTargetPosition = target;
        mDispatcher.initData(target, true, false);
        //mDispatcher.loadCard(target);
        mMajorVideo.seekTo((int) target);
        mDispatcher.seek(target);

        if (mMessageHelper != null)
            mMessageHelper.fetchMessage((int) target);
        if (mDanmuHelper != null)
            mDanmuHelper.onSeek(target);
    }

    @Override
    public void rescheduleHideMessage() {
        //重新开始工具栏的时序动画
        mHandler.removeCallbacksAndMessages(null);

        mHandler.sendEmptyMessageDelayed(CODE_HIDE, TOOL_DURATION);
    }

    @Override
    public void hideToolsBar() {
        mHandler.removeCallbacksAndMessages(null);
        mHandler.sendEmptyMessage(CODE_HIDE);
    }

    @Override
    public void clearHideMsg() {
        mHandler.removeCallbacksAndMessages(null);
        mHandler.sendEmptyMessage(CODE_HIDE_TOOLS);
    }

    @Override
    public void hideGoods() {
        mPlayController.hideGoodsLayout();
    }

    @Override
    public void manageFlingEvent(boolean canFling) {
        if (mMultiCameraView != null)
            mMultiCameraView.manageFlingEvent(canFling);
    }

    @Override
    public void changeDefinition(String des, int type) {
        mMajorVideoHelper.changeDefinition(des, type);
        mMultiCameraView.changeDefinition(des, type);
        mMajorVideo.showLoading();
    }

    @Override
    public void showScaleGuide() {
        if (GuideConstants.isScaleGuideShowed(mPlayActivity))
            return;

        mHandler.removeMessages(CODE_HIDE);
        mHandler.removeMessages(CODE_SHOW);
        if (!mToolVisible.get()) {
            manageToolVisibleState(false);
        }
        GuideConstants.showScaleGuide(mPlayActivity, mPlayController.getZoomView(), new OnGuidePerformedListener() {
            @Override
            public void onPerformed(String id) {
                mHandler.removeMessages(CODE_HIDE);
                mHandler.sendEmptyMessageDelayed(CODE_HIDE, TOOL_DURATION);
            }
        });

        GuideConstants.scaleGuidePerformed(mPlayActivity);
    }

    @Override
    public boolean isVrMode(boolean onMajorVideo) {
        if (mMultiCameraView != null) {
            return mMultiCameraView.isVrMode(onMajorVideo);
        }
        return false;
    }

    @Override
    public int switchInteractiveMode() {
        if (mMultiCameraView != null)
            return mMultiCameraView.switchInteractiveMode();
        return 0;
    }

    @Override
    public int switchDisplayMode() {
        if (mMultiCameraView != null)
            return mMultiCameraView.switchDisplayMode();
        return 0;
    }

    /**
     * implements AbstractController.IControllerCallback
     */
    @Override
    public void onGoodsAdd(List<GoodsItem> data) {
        if (data == null || data.size() == 0)
            return;
        mPlayController.addGoodsToFavor(data);

        mHandler.removeCallbacksAndMessages(null);
        mHandler.sendEmptyMessageDelayed(CODE_HIDE, TOOL_DURATION);
    }

    @Override
    public void managerTools() {
        //manage tool to show or hideTitle
        manageTools();
    }

    @Override
    public void reserveFullScreen(boolean exitMultiVideo) {
        mPlayController.reserveFullScreen(exitMultiVideo);
    }

    @Override
    public void toFullScreen(String title, boolean isVr) {
        mPlayController.toFullScreen(title, isVr);
    }

    @Override
    public void switchGoodsHotpotSize(boolean fullScreen) {
        //镜头切换的同时切换物品的热点的size
        mPlayController.switchGoodsHotpotSize(fullScreen);
    }

    @Override
    public void cancelGoods(String id) {
        mPlayController.removeGoodsFromFavor(id);
    }

    @Override
    public void updateTitle(String title) {
        mPlayController.updateTitle(title);
    }

    @Override
    public void setBg(String url) {
        loadBgBitmap(url);
    }

    @Override
    public void manageProgress(boolean speedUp, float ratio, boolean doSeek) {
        mPlayController.manageProgress(speedUp, ratio, doSeek);
    }

    @Override
    public long getCurrentProgress() {
        if (MultiVideoBalanceAdapter.getInstance().isLowExperience()) {
            return mCurrentProgress;
        } else {
            long progress = 0;
            if (mMajorVideoHelper != null)
                progress = mMajorVideoHelper.getCurrentProgress();
            return progress;
        }
    }

    @Override
    public long getDuration() {
        long duration = 0;
        if (mMajorVideoHelper != null)
            duration = mMajorVideoHelper.getDuration();
        return duration;
    }

    @Override
    public int[] getCartLocation() {
        return mPlayController.getCartLocation();
    }

    @Override
    public void showTools(int time) {
        manageTools(time);
    }

    @Override
    public void cancelSeek() {
        mPlayController.cancelSeek();
    }

    @Override
    public void hideFavorCart() {
        mPlayController.hideFavorCartIfVisible();
    }

    @Override
    public void videoTipsIn(String tips) {
        mPlayController.videoTxtTipsIn(tips);
    }

    @Override
    public void videoTipsOut() {
        mPlayController.videoTxtTipsOut();
    }

    @Override
    public void mainVideoChanged(int current) {
        mPlayController.displayHotpot(current);
    }

    @Override
    public void initToolBar(boolean onMajorVideo) {
        mPlayController.initToolBar(onMajorVideo);
    }

    @Override
    public void endUpdateProgress() {
        mPlayController.endUpdateProgress();
    }

    @Override
    public void onStartTrackingTouch() {
        mPlayController.onStartTrackingTouch();
    }

    @Override
    public void pauseAllPlayers() {
//        mPlayController.pause();
        mPlayController.pauseWhenFreeze();
        videoTipsIn("多视角有点卡,暂时只播放主视角视频哟~");
    }

    @Override
    public boolean isPlaying() {
        return mPlayController.isPlaying();
    }

    @Override
    public void updateProgressBySubVideo(long current) {
        mCurrentProgress = current;
        mMultiCameraView.quitWait(mMajorVideoHelper);
        if (mPlayController.updateProgress(current, getDuration())) {
            mDispatcher.loadCard(current);
        }
    }

    @Override
    public void updateBg(String url) {
        if (StringUtils.isNotBlank(url))
            loadBgBitmap(url);
    }

    private void manageTools() {
        if (mPlayController != null && mPlayController.interceptManageEvent()) {
            return;
        }
        mHandler.removeMessages(CODE_SHOW);
        mHandler.removeMessages(CODE_HIDE);
        if (mToolVisible.get())
            mHandler.sendEmptyMessage(CODE_HIDE);
        else {
            mHandler.sendEmptyMessage(CODE_SHOW);
            mHandler.sendEmptyMessageDelayed(CODE_HIDE, TOOL_DURATION);
        }
    }

    private void manageTools(int time) {
        if (mToolVisible.get())
            return;
        mHandler.sendEmptyMessage(CODE_SHOW);
        mHandler.sendEmptyMessageDelayed(CODE_HIDE, time);
    }


    public void showLoading() {
        mMajorVideo.showLoading();
    }

    public void hideLoading() {
        mMajorVideo.hideLoading();
    }

    private void removeLoadint() {
        if (mLoadintAnimating.get())
            return;
        mLoadintAnimating.set(true);
        if (mInitLoading.getVisibility() == View.VISIBLE) {
            ObjectAnimator anim = ObjectAnimator.ofFloat(mInitLoading, "alpha", 1f, 0f);
            anim.setDuration(150);
            anim.addListener(new AnimatorListenerAdapter() {

                @Override
                public void onAnimationEnd(Animator animation) {
                    mLoadintAnimating.set(false);
                    mInitLoading.setVisibility(View.GONE);
                }

            });
            anim.start();
        }
    }

    private void resetLoading() {
        if (mInitLoading.getVisibility() != View.VISIBLE) {
            ObjectAnimator anim = ObjectAnimator.ofFloat(mInitLoading, "alpha", 0f, 1f);
            anim.setDuration(150);
            anim.addListener(new AnimatorListenerAdapter() {

                @Override
                public void onAnimationStart(Animator animation) {
                    mInitLoading.setVisibility(View.VISIBLE);
                    mInitLoading.setAlpha(0f);
                }

            });
            anim.start();
        }
    }

    public void loadChannelDetail(final boolean videoIsNotNull) {
        if(mChannel == null)
            return;
        HashMap<String, String> parameterMap = new HashMap<>();
        parameterMap.put(OpenApi.API_METHOD, OpenApi.CHANNEL_DETAIL);
        parameterMap.put("videoid", mChannel.videoid);
        BFJSONRequest request = new BFJSONRequest(ChannelDetailModel.class, parameterMap, new Response.Listener<ChannelDetailModel>() {

            @Override
            public void onResponse(ChannelDetailModel response) {
                if (response.success() && response.data != null) {
                    //如果返回异常数据
                    if(response.data.getVideo() == null) {
                        if(!videoIsNotNull) {
                            mPlayActivity.finish();
                        }
                        return;
                    }

                    mChannel = response.data;

                    if (videoIsNotNull) {
                        if (mPlayController != null)
                            mPlayController.updateContent(mChannel);
                    } else {
                        if (!loadModule()) {
                            mPlayActivity.finish();
                        }
                    }
                }
            }

            @Override
            public void onErrorResponse(VolleyError error) {
            }

            @Override
            public void onStart() {
            }
        });
        request.setTag(TAG);
        HttpRequestLoader.getInstance(mPlayActivity).startCacheLoader("", request, true);
    }

    private void loadBgBitmap(String url) {
        if (StringUtils.isBlank(url)) {
            return;
        }

        if (!url.contains("aube-tv")) {
            ImageLoader.getInstance(mPlayActivity).preloadBitmap(url, 400, 400, new ImageLoader.IPreloadCallback<Bitmap>() {
                @Override
                public void onSuccess(Bitmap bitmap) {
                    try {
                        mBgImg.setImageBitmap(BlurUtil.apply(mPlayActivity, bitmap));
                    } catch (Exception e) {
                        e.printStackTrace();
                        mBgImg.setImageBitmap(bitmap);
                    }
                }

                @Override
                public void onFail() {

                }
            });
        } else {
            ImageLoader.getInstance(mPlayActivity).fillImage(mBgImg, ImageParamUtils.getImgUrl(url, 400, 400, 20, 20));
        }
    }

    /**
     * 以下是和PlayActivity的交互
     */

    public void continueAfterPermissionGet() {
        mPlayController.continueAfterPermissionGet();
    }

    public void resumeFromLogin() {
        if (mPlayController != null)
            mPlayController.resumeFromLogin();
    }

    public boolean onBackPressed() {
        if (mPlayController != null && mPlayController.onBackPressed())
            return true;

        if (mMultiCameraView != null && mMultiCameraView.onBackPressed())
            return true;

        if (mChannel != null)
            DataManager.getInstance(mPlayActivity).save(mChannel.videoid);
        //清空所有的数据
        if (mPlayController != null)
            mPlayController.onDestroy();

        mDanmuHelper.onDestroy();
        mMessageHelper.onDestroy();

        if (mMajorVideoHelper != null)
            mMajorVideoHelper.onDestroy();

        if (mDispatcher != null)
            mDispatcher.onDestroy();

        return false;
    }

    /**
     * 有三种情况会触发此方法:
     * 1.statusbar下拉或者收起
     * 2.锁屏或者开屏
     * 3.HOME健或者从HOME恢复
     * 如果是statusbar模式,处理逻辑如下:
     * 如果失去焦点前是播放状态,回来应该保持播放状态
     * 如果失去焦点前是暂停状态,回来应该是暂停状态
     * <p/>
     * mInvokeWindowFocusChanged只有再onResume或者onPause调用才会被重置,而statusbar模式中并不会调用这两个方法
     * 所以它是用来区分statusbar模式和其他两种模式的锁
     * <p/>
     * 锁屏模式和HOME健模式回来均保持视屏为暂停状态
     *
     * @param hasFocus
     */
    public void onWindowFocusChanged(boolean hasFocus) {
        if (mFocusState == null)
            mFocusState = new AtomicBoolean(hasFocus);
        else if (hasFocus == mFocusState.get())
            return;

        mFocusState.set(hasFocus);

        Utils.Log(TAG, "window focus changed==============================" + (hasFocus ? "focus" : "not focus") + "___invoke:" + (mInvokeWindowFocusChanged.get() ? "yes" : "no"));
        if (!mInvokeWindowFocusChanged.get()) {
            mInvokeWindowFocusChanged.set(true);
        } else {
            Utils.Log(TAG, "----mInvokeWindowFocusChanged:true");
            if (mMajorVideoHelper != null) {
                if (hasFocus && !mMajorVideoHelper.isPlaying()) {
                    if (mFocusSwitchEnable.get()) {
                        mPlayController.play();
                        Utils.Log(TAG, "----start play");
                    }
                } else if (!hasFocus) {
                    if (mMajorVideoHelper.isPlaying()) {
                        Utils.Log(TAG, "----start stop");
                        mPlayController.pause();
                        mFocusSwitchEnable.set(true);
                    } else {
                        mFocusSwitchEnable.set(false);
                    }
                }
            }
        }
    }

    public void onAdFinished() {
        if (mMajorVideoHelper != null)
            mMajorVideoHelper.adFinished();
    }

    public void toWriteDanmu() {
        mHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                mPlayController.toWriteDammu(true);
            }
        }, 1000);
    }

    public void onResume() {
        if (mMultiCameraView != null)
            mMultiCameraView.onResume();
        mInvokeWindowFocusChanged.set(false);

        Utils.Log(TAG, "----oResume");

        if (mPlayController != null && !mPlayController.isPlaying()) {
            manageToolVisibleState(false);

            mRestartToolVisibilityLooper.set(true);
        }
    }

    public void onPause() {
        if (mMultiCameraView != null)
            mMultiCameraView.onPause();
        mInvokeWindowFocusChanged.set(false);

        Utils.Log(TAG, "----onPause");

        if (mPlayController != null && mPlayController.isPlaying()) {
            mPlayController.pause();
        }

        mHandler.removeMessages(CODE_HIDE);
        mHandler.removeMessages(CODE_SHOW);
    }

    public void onDestroy() {
        if (mMultiCameraView != null)
            mMultiCameraView.onDestroy();
//        if(mPlayController != null)
//            mPlayController.onDestroy();

        AubeStatisticTool.getInstance(mPlayActivity).report(AubeStatisticEvents.VIDEO_PLAY_DATATRAFFICT,
                AubeStatisticEvents.formatValues(new EventValuePair("vid", mChannel.videoid),
                        new EventValuePair("data_traffic", String.valueOf(StaticApplicationContext.receivedDataSize))));
    }

}
